package icedot.library.common.ui;

import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;

import icedot.library.common.base.Logger;
import icedot.library.common.utils.CommonFun;

/**
 * Created by IceDot on 2016/4/28.
 */
public class UpdateManager implements UpdateHead.FootListener
{
    public enum Status
    {
        Top,
        Bottom,
        Other,
    }

    private UpdateHead _headView;
    private Scroller   _scrollerHead;
    private UpdateFoot _footView;
    private Scroller   _scrollerFoot;
    private float _lastY = -1;
    private Status  _status;
    private boolean _enableHead;
    private boolean _enableFoot;
    private View    _parentView;
    private Context _context;


    public UpdateManager(Context context, View parentView)
    {
        _context = context;
        _scrollerHead = new Scroller(context, new DecelerateInterpolator());
        _scrollerFoot = new Scroller(context, new DecelerateInterpolator());
        _status = Status.Other;
        _enableHead = true;
        _enableFoot = true;
        _parentView = parentView;
    }

    public void setStatus(Status st)
    {
        _status = st;
    }

    public void setEnableHead(boolean enable)
    {
        _enableHead = enable;
    }

    public void setEnableFoot(boolean enable)
    {
        _enableFoot = enable;
    }

    public boolean onTouchEvent(MotionEvent ev)
    {
        if (_status == Status.Other)
        {
            reset();
            return true;
        }

        switch (ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                if (_enableHead && _status == Status.Top)
                {
                    _lastY = ev.getRawY();
                    _headView.setState(UpdateHead.Status.PRESSEDDOWN);
                }
                else if (_enableFoot && _status == Status.Bottom && _footView.getState() != UpdateFoot.Status.FINISHALLDATA)
                {
                    _lastY = ev.getRawY();
                    _footView.setState(UpdateFoot.Status.PRESSEDDOWN);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (_lastY == -1)
                {
                    _lastY = ev.getRawY();
                }
                if (_enableHead && _status == Status.Top)
                {
                    _headView.setState(UpdateHead.Status.PRESSEDMOVE);
                    updateHeadHeight(ev.getRawY());
                }
                else if (_enableFoot && _status == Status.Bottom && _footView.getState() != UpdateFoot.Status.FINISHALLDATA)
                {
                    updateFootHeight(ev.getRawY());
                }
                break;
            case MotionEvent.ACTION_UP:
                if (_enableHead && _footView.getState() != UpdateFoot.Status.UPDATEDATA && _headView.getVisiableHeight() > 0)
                {
                    _headView.setState(UpdateHead.Status.PRESSEDUP);
                    resetHead();
                }
                else
                {
                    resetHead();
                }
                if (_enableFoot && _headView.getState() != UpdateHead.Status.UPDATEDATA && _footView.getVisiableHeight() > 0 && _footView.getState() != UpdateFoot.Status.FINISHALLDATA)
                {
                    _footView.setState(UpdateFoot.Status.PRESSEDUP);
                    resetFoot();
                }
                else
                {
                    resetFoot();
                }
                _lastY = -1;
                break;
            default:
                _lastY = -1;
                break;
        }
        return false;
    }

    public void reset()
    {
        resetHead();
        resetFoot();
    }

    public void resetHead()
    {
        if (_headView.getVisiableHeight() == 0)
        {
            return;
        }
        UpdateHead.Status status = _headView.getState();
        int               height = 0;
        if (status == UpdateHead.Status.UPDATEDATA)
        {
            height = _headView.getMinUpdateHeight();
        }
        _scrollerHead.startScroll(0, _headView.getVisiableHeight(), 0, -(_headView.getVisiableHeight() - height), 800);
        _parentView.invalidate();
    }

    public void resetFoot()
    {
        if (_footView.getVisiableHeight() == 0)
        {
            return;
        }
        UpdateFoot.Status status = _footView.getState();
        int               height = 0;
        if (status == UpdateFoot.Status.UPDATEDATA || status == UpdateFoot.Status.FINISHALLDATA)
        {
            height = _footView.getMinLoadHeight();
        }
        _scrollerFoot.startScroll(0, _footView.getVisiableHeight(), 0, -(_footView.getVisiableHeight() - height), 800);
        _parentView.invalidate();
    }

    public void setUpdateHeadView(UpdateHead view)
    {
        _headView = view;
        _headView.useHeadContent();
    }

    public void setUpdateFootView(UpdateFoot view)
    {
        _footView = view;
        _footView.useFootContent();
    }

    public void computeScroll()
    {
        if (_scrollerHead.computeScrollOffset())
        {
//            Logger.showDebugMsg("ScrollHead", "Y:" + _scrollerHead.getCurrY());
            if (_headView.getVisiableHeight() > 0)
            {
                _headView.setVisiableHeight(_scrollerHead.getCurrY());
            }
            _parentView.postInvalidate();
        }
        if (_scrollerFoot.computeScrollOffset())
        {
//            Logger.showDebugMsg("ScrollFoot", "Y:" + _scrollerFoot.getCurrY());
            if (_footView.getVisiableHeight() > 0)
            {
                _footView.setVisiableHeight(_scrollerFoot.getCurrY());
            }
            _parentView.postInvalidate();
        }
    }

    /**
     * 头部完成
     */
    public void completeHead()
    {
        if (_headView.getState() == UpdateHead.Status.UPDATEDATA)
        {
            _headView.setState(UpdateHead.Status.RESET);
            if (_headView.getVisiableHeight() == 0)
            {
                return;
            }
            _scrollerHead.startScroll(0, _headView.getVisiableHeight(), 0, -_headView.getVisiableHeight(), 800);
            _parentView.invalidate();
        }

    }

    public void completeFoot()
    {
        if (_footView.getState() == UpdateFoot.Status.UPDATEDATA)
        {
            _footView.setState(UpdateFoot.Status.RESET);
            if (_footView.getVisiableHeight() == 0)
            {
                return;
            }
            _scrollerFoot.startScroll(0, _footView.getVisiableHeight(), 0, -_footView.getVisiableHeight(), 800);
            _parentView.invalidate();
        }
    }

    /**
     * 已经全部加载完成
     */
    public void setFootNoMore()
    {
        _footView.setState(UpdateFoot.Status.RESET);
        _footView.setState(UpdateFoot.Status.FINISHALLDATA);
        resetFoot();
    }


    public void clearFootFinish()
    {
        if (_footView.getState() == UpdateFoot.Status.FINISHALLDATA)
        {
            _footView.setState(UpdateFoot.Status.RESET);
            if (_footView.getVisiableHeight() == 0)
            {
                return;
            }
            _scrollerFoot.startScroll(0, _footView.getVisiableHeight(), 0, -_footView.getVisiableHeight(), 800);
            _parentView.invalidate();
        }
    }

    /**
     * 监听这个事件来获取拖动的结果
     *
     * @param ls
     */
    public void setUpdateViewListener(UpdateViewListener ls)
    {
        _headView.setNotifyListener(ls, this);
        _footView.setNotifyListener(ls);
    }

    private void updateHeadHeight(float y)
    {
        if (_headView == null || !_enableHead)
        {
            return;
        }
        int   maxHeight = _headView.getMaxUpdateHead();
        float deltaY    = y - _lastY;
        if (deltaY > 0)
        {
            if (deltaY >= maxHeight)
            {
                deltaY = maxHeight;
            }
            _headView.setVisiableHeight((int) deltaY);
//            Logger.showDebugMsg("headHeight:" + deltaY + " y:" + y + " lastY:" + _lastY);
        }
        else
        {
            _headView.setVisiableHeight(0);
        }
    }

    /**
     * 修改列表底部的高度
     *
     * @param y
     */
    private void updateFootHeight(float y)
    {
        if (_footView == null || !_enableFoot)
        {
            return;
        }

        int   maxHeight = _footView.getMaxLoadHeight();
        float deltaY    = _lastY - y;
        if (deltaY > 0)
        {
            if (deltaY >= maxHeight)
            {
                deltaY = maxHeight;
            }
            _footView.setVisiableHeight((int) deltaY);
        }
    }

    public int getHeadHeight()
    {
        return _headView.getVisiableHeight();
    }

    public int getFootHeight()
    {
        return _footView.getVisiableHeight();
    }
}
